package com.hup.timer.service.gesture;

import com.hup.timer.service.gesture.TimerWindowGesture.GestureCallback;
import com.hup.timer.view.TimerWindow;
import com.hup.timer.view.customView.TimeView;
import com.hup.utils.commons.hardware.MouseLooper;
import com.hup.utils.commons.hardware.MouseLooper.MlPermitCallback;
import com.hup.utils.commons.hardware.ScreenUtil;
import lombok.extern.log4j.Log4j2;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * @author hugan
 * @date 2020/4/6
 */
@Log4j2
public class SetSizeListener extends MouseAdapter implements MlPermitCallback {

    private final TimerWindow win;
    private final TimeView timeView;
    private final GestureCallback callback;

    private final MouseLooper mouseLooper;
    private Insets sc;
    private int minViewHei, maxViewHei;
    
    /**
     * 是否有改变过
     */
    private boolean hadChanged;
    /**
     * 磁性贴紧边缘
     */
    private boolean isStickRight, isStickBottom;
    private int fontSize0;
    private int lastFontSize;
    /**
     * 调节时,是否已经到达了上下界
     */
    private boolean touchMin, touchMax;

    public SetSizeListener(GestureCallback callback) {
        this.win = (TimerWindow) callback.getWindow();
        timeView = win.getTimeView();
        this.callback = callback;
        mouseLooper = new MouseLooper(this);
    }

    /**
     * @param e shiftDown+isLeftButton
     */
    @Override
    public void mousePressed(MouseEvent e) {
        fontSize0 = timeView.getFont().getSize();
        log.info("激活设置大小, fontSize0={}", fontSize0);
        //每次按下后,都更新最新的分辨率和限制大小
        sc = ScreenUtil.getScreenUsableCoor();
        minViewHei = 21;
        maxViewHei = (int) ((sc.bottom - sc.top) / 2.0);

        isStickRight = false;
        isStickBottom = false;
        if (win.getX() + win.getWidth() >= sc.right) isStickRight = true;
        if (win.getY() + win.getHeight() >= sc.bottom) isStickBottom = true;
        touchMin = touchMax = false;
        mouseLooper.mousePressed(e);
    }

    /**
     * @param isLoopY 总是true的
     */
    @Override
    public boolean canLoop(boolean isLoopY, boolean isDown) {
        log.debug("isDown={}, touchMin={}, touchMax={}", isDown, touchMin, touchMax);
        return !((isDown && touchMin) || (!isDown && touchMax));
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        int yDiff = mouseLooper.mouseDraggedY(e);
        log.debug("[{},{}], diff={}", e.getXOnScreen(), e.getYOnScreen(), yDiff);
        yDiff = yDiff / 3;//降低变化率
        int fontSize = fontSize0 + (-(yDiff));
        
        Font old = timeView.getFont();
        Font newFont = new Font(old.getName(), old.getStyle(), fontSize);

        touchMin = touchMax = false;
        Dimension viewSize = timeView.getViewSize(newFont);
        if (viewSize.height <= minViewHei) {
            callback.onSizeLimit();
            touchMin = true;
            return;
        } else if (viewSize.height >= maxViewHei) {
            touchMax = true;
            callback.onSizeLimit();
            return;
        }
        log.debug("yDiff={}, fontSize={}, viewSize={}", yDiff, fontSize, viewSize);

        //调整大小
        boolean larger = fontSize > lastFontSize;
        if (larger) {
            win.setSize(viewSize);
            handleStickScreen(viewSize);
            timeView.setFont(newFont);
        } else {
            handleStickScreen(viewSize);
            timeView.setFont(newFont);
            win.setSize(viewSize);
        }
        lastFontSize = fontSize;

        hadChanged = true;
    }

    private void handleStickScreen(Dimension viewSize) {
        //处理贴紧屏幕的情况
        int viewX = win.getX();
        int viewY = win.getY();

        //原来没贴紧,更新后贴紧
        if (!isStickRight && viewX + viewSize.getWidth() >= sc.right) isStickRight = true;
        if (!isStickBottom && viewY + viewSize.getHeight() >= sc.bottom) isStickBottom = true;

        if(isStickRight || isStickBottom) {
            viewX = isStickRight ? (int) (sc.right - viewSize.getWidth()) : viewX;
            viewY = isStickBottom ? (int) (sc.bottom - viewSize.getHeight()) : viewY;
            win.setLocation(viewX, viewY);
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (hadChanged) {
            callback.afterChangedSize(lastFontSize);
            hadChanged = false;
        }
    }

}
